#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import logging
from typing import Dict, List, Any, Tuple, Optional, Union, Set
from datetime import datetime
import json
import time
import zlib
import base64

from tree_sitter import Language, Parser, Tree, Node
import tree_sitter_java as tsjava

from parser.ast_to_kg_interface import ASTToKGConverter
from vector_store.factory import VectorStoreFactory
from vector_store.node_vector_processor import NodeVectorProcessor
from parser.utils import ContentCompressor

# 获取logger
logger = logging.getLogger(__name__)

class JavaASTToKG(ASTToKGConverter):
    """
    Java语言的抽象语法树到知识图谱转换器
    """

    def __init__(self, enable_vector_storage: bool = False):
        """初始化Java AST到KG转换器
        
        Args:
            enable_vector_storage: 是否启用向量存储功能
        """
        self.parser = None
        self.initialize_parser()
        # 添加实例变量用于跟踪所有已创建的顶点
        self.created_vertices = set()
        # 添加实例变量用于跟踪ID映射
        self.id_mappings = {}
        # 添加实例变量用于跟踪哪些节点是占位符
        self.placeholder_vertices = set()
        # 向量存储相关
        self.enable_vector_storage = enable_vector_storage
        self.vector_processor = None
        
        if enable_vector_storage:
            # 使用工厂创建向量存储，工厂会自行从config中获取配置信息
            vector_store = VectorStoreFactory.create_vector_store()
            # 创建节点向量处理器，所需配置由VectorStoreFactory已经处理
            self.vector_processor = NodeVectorProcessor(vector_store=vector_store)
            logger.info("向量存储初始化成功")

    def initialize_parser(self) -> None:
        """
        初始化Java语法分析器
        """
        try:
            JAVA_LANGUAGE = Language(tsjava.language())
            self.parser = Parser(JAVA_LANGUAGE)
            logger.info("Java解析器初始化成功")
        except Exception as e:
            logger.error(f"Java解析器初始化失败: {str(e)}")
            raise

    def parse_code(self, code: str) -> Optional[Tree]:
        """
        解析Java代码字符串，生成语法树

        Args:
            code: 要解析的Java代码字符串

        Returns:
            解析生成的语法树对象，解析失败时返回None
        """
        try:
            tree = self.parser.parse(bytes(code, 'utf8'))
            return tree
        except Exception as e:
            logger.error(f"解析Java代码失败: {str(e)}")
            return None

    def parse_file(self, file_path: str) -> Optional[Tree]:
        """
        解析Java文件，生成语法树

        Args:
            file_path: 要解析的Java文件路径

        Returns:
            解析生成的语法树对象，解析失败时返回None
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                code = f.read()
            return self.parse_code(code)
        except Exception as e:
            logger.error(f"解析文件 {file_path} 失败: {str(e)}")
            return None

    def parse_directory(self, directory_path: str, file_extension: str = '.java') -> Dict[str, Tree]:
        """
        解析目录中所有Java文件

        Args:
            directory_path: 要解析的目录路径
            file_extension: 文件扩展名，默认为'.java'

        Returns:
            文件路径到对应语法树的映射
        """
        result = {}
        for root, _, files in os.walk(directory_path):
            for file in files:
                if file.endswith(file_extension):
                    file_path = os.path.join(root, file)
                    tree = self.parse_file(file_path)
                    if tree:
                        result[file_path] = tree

        logger.info(f"已解析 {len(result)} 个Java文件")
        return result

    def _get_comment_nodes(self, root_node: Node) -> List[Dict[str, Any]]:
        """
        提取Java代码中的注释节点

        Args:
            root_node: 语法树根节点

        Returns:
            注释节点列表
        """
        comment_nodes = []

        # 查找行注释
        line_comments = self.find_all_nodes(root_node, "line_comment")
        for node in line_comments:
            comment_nodes.append({
                "node": node,
                "type": "LINE",
                "line_start": node.start_point[0] + 1,
                "line_end": node.end_point[0] + 1
            })

        # 查找块注释
        block_comments = self.find_all_nodes(root_node, "block_comment")
        for node in block_comments:
            comment_nodes.append({
                "node": node,
                "type": "BLOCK",
                "line_start": node.start_point[0] + 1,
                "line_end": node.end_point[0] + 1
            })

        return comment_nodes

    def _extract_package_info(self, root_node: Node, code_bytes: bytes) -> Optional[str]:
        """
        提取Java代码中的包信息

        Args:
            root_node: 语法树根节点
            code_bytes: 源代码字节

        Returns:
            包名或None
        """
        package_nodes = self.find_all_nodes(root_node, "package_declaration")
        if package_nodes:
            package_node = package_nodes[0]
            name_node = None
            for child in package_node.children:
                if child.type == "scoped_identifier":
                    name_node = child
                    break

            if name_node:
                return self.get_node_text(name_node, code_bytes)

        return None

    def _extract_imports(self, root_node: Node, code_bytes: bytes) -> List[Dict[str, Any]]:
        """
        提取Java代码中的导入语句

        Args:
            root_node: 语法树根节点
            code_bytes: 源代码字节

        Returns:
            导入信息列表
        """
        imports = []
        import_nodes = self.find_all_nodes(root_node, "import_declaration")

        for node in import_nodes:
            import_info = {
                "node": node,
                "line_number": node.start_point[0] + 1,
                "import_type": "IMPORT"
            }

            # 检查是否为静态导入
            is_static = False
            for child in node.children:
                if child.type == "static" and self.get_node_text(child, code_bytes) == "static":
                    is_static = True
                    break

            import_info["is_static"] = is_static

            # 提取导入的名称
            for child in node.children:
                if child.type == "scoped_identifier" or child.type == "identifier":
                    import_info["import_name"] = self.get_node_text(child, code_bytes)
                    break

            imports.append(import_info)

        return imports

    def _extract_class_info(self, node: Node, code_bytes: bytes, package_name: Optional[str] = None) -> Dict[str, Any]:
        """
        提取类信息

        Args:
            node: 类声明节点
            code_bytes: 源代码字节
            package_name: 包名

        Returns:
            类信息字典
        """
        class_info = {
            "node": node,
            "type": "class",
            "line_start": node.start_point[0] + 1,
            "line_end": node.end_point[0] + 1,
            "visibility": "default",
            "annotations": []  # 新增：存储注解列表
        }

        # 新增：提取类注解
        self._extract_annotations(node, code_bytes, class_info)

        # 获取类名
        name_node = None
        for child in node.children:
            if child.type == "identifier":
                name_node = child
                break

        if name_node:
            class_info["name"] = self.get_node_text(name_node, code_bytes)
            if package_name:
                class_info["full_name"] = f"{package_name}.{class_info['name']}"
            else:
                class_info["full_name"] = class_info["name"]

        # 检查修饰符
        modifiers = self.find_all_nodes(node, "modifiers")
        if modifiers:
            for modifier in modifiers:
                modifier_text = self.get_node_text(modifier, code_bytes)
                if "public" in modifier_text:
                    class_info["visibility"] = "public"
                elif "private" in modifier_text:
                    class_info["visibility"] = "private"
                elif "protected" in modifier_text:
                    class_info["visibility"] = "protected"

                if "abstract" in modifier_text:
                    class_info["is_abstract"] = True

        # 检查超类
        superclass_node = None
        for child in node.children:
            if child.type == "superclass":
                superclass_node = child
                break

        if superclass_node:
            for child in superclass_node.children:
                if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                    class_info["extends"] = self.get_node_text(child, code_bytes)
                    break

        # 检查接口实现
        interfaces_node = None
        for child in node.children:
            if child.type == "super_interfaces":
                interfaces_node = child
                break

        if interfaces_node:
            interfaces = []
            # 查找type_list节点
            type_list_node = None
            for child in interfaces_node.children:
                if child.type == "type_list":
                    type_list_node = child
                    break

            # 如果找到type_list节点，遍历其子节点获取类型
            if type_list_node:
                for child in type_list_node.children:
                    if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                        interfaces.append(self.get_node_text(child, code_bytes))
            # 兼容旧版本解析树结构，直接从super_interfaces子节点查找类型
            else:
                for child in interfaces_node.children:
                    if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                        interfaces.append(self.get_node_text(child, code_bytes))

            if interfaces:
                class_info["implements"] = interfaces

        return class_info

    def _extract_interface_info(self, node: Node, code_bytes: bytes, package_name: Optional[str] = None) -> Dict[str, Any]:
        """
        提取接口信息

        Args:
            node: 接口声明节点
            code_bytes: 源代码字节
            package_name: 包名

        Returns:
            接口信息字典
        """
        interface_info = {
            "node": node,
            "type": "interface",
            "line_start": node.start_point[0] + 1,
            "line_end": node.end_point[0] + 1,
            "visibility": "default"
        }

        # 获取接口名
        name_node = None
        for child in node.children:
            if child.type == "identifier":
                name_node = child
                break

        if name_node:
            interface_info["name"] = self.get_node_text(name_node, code_bytes)
            if package_name:
                interface_info["full_name"] = f"{package_name}.{interface_info['name']}"
            else:
                interface_info["full_name"] = interface_info["name"]

        # 检查修饰符
        modifiers = self.find_all_nodes(node, "modifiers")
        if modifiers:
            for modifier in modifiers:
                modifier_text = self.get_node_text(modifier, code_bytes)
                if "public" in modifier_text:
                    interface_info["visibility"] = "public"
                elif "private" in modifier_text:
                    interface_info["visibility"] = "private"
                elif "protected" in modifier_text:
                    interface_info["visibility"] = "protected"

        # 检查扩展的接口
        extends_node = None
        for child in node.children:
            if child.type == "extends_interfaces":
                extends_node = child
                break

        if extends_node:
            extends_interfaces = []

            # 查找type_list节点
            type_list_node = None
            for child in extends_node.children:
                if child.type == "type_list":
                    type_list_node = child
                    break

            # 如果找到type_list节点，遍历其子节点获取类型
            if type_list_node:
                for child in type_list_node.children:
                    if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                        extends_interfaces.append(self.get_node_text(child, code_bytes))
            # 兼容旧版本解析树结构，直接从extends_interfaces子节点查找类型
            else:
                for child in extends_node.children:
                    if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                        extends_interfaces.append(self.get_node_text(child, code_bytes))

            if extends_interfaces:
                interface_info["extends"] = extends_interfaces

        return interface_info

    def _extract_method_info(self, node: Node, code_bytes: bytes, class_name: str = "", package_name: Optional[str] = None) -> Dict[str, Any]:
        """
        提取方法信息

        Args:
            node: 方法声明节点
            code_bytes: 源代码字节
            class_name: 方法所属类名
            package_name: 包名

        Returns:
            方法信息字典
        """
        method_info = {
            "node": node,
            "line_start": node.start_point[0] + 1,
            "line_end": node.end_point[0] + 1,
            "is_static": False,
            "is_constructor": False,
            "visibility": "default",
            "parameters": [],
            "annotations": []  # 新增：存储注解列表
        }

        # 新增：提取方法注解
        self._extract_annotations(node, code_bytes, method_info)

        # 获取方法名
        name_node = None
        for child in node.children:
            if child.type == "identifier":
                name_node = child
                break

        if name_node:
            method_info["name"] = self.get_node_text(name_node, code_bytes)

            # 判断是否为构造函数
            if class_name and method_info["name"] == class_name:
                method_info["is_constructor"] = True
                method_info["return_type"] = None

            # 构建完整方法名 - 始终使用类的全限定名+方法名
            if package_name and class_name:
                class_full_name = f"{package_name}.{class_name}"
                method_info["full_name"] = f"{class_full_name}.{method_info['name']}"
            elif class_name:
                method_info["full_name"] = f"{class_name}.{method_info['name']}"
            else:
                method_info["full_name"] = method_info["name"]

        # 提取方法返回类型
        if not method_info.get("is_constructor", False):
            return_type_node = None
            for child in node.children:
                if child.type == "type_identifier" or child.type == "primitive_type" or child.type == "void_type" or child.type == "scoped_type_identifier":
                    return_type_node = child
                    break

            if return_type_node:
                method_info["return_type"] = self.get_node_text(return_type_node, code_bytes)

        # 检查修饰符
        modifiers = self.find_all_nodes(node, "modifiers")
        if modifiers:
            for modifier in modifiers:
                modifier_text = self.get_node_text(modifier, code_bytes)
                if "public" in modifier_text:
                    method_info["visibility"] = "public"
                elif "private" in modifier_text:
                    method_info["visibility"] = "private"
                elif "protected" in modifier_text:
                    method_info["visibility"] = "protected"

                if "static" in modifier_text:
                    method_info["is_static"] = True

                if "abstract" in modifier_text:
                    method_info["is_abstract"] = True

        # 提取参数信息
        formal_parameters_node = None
        for child in node.children:
            if child.type == "formal_parameters":
                formal_parameters_node = child
                break

        if formal_parameters_node:
            parameters = []
            for i, child in enumerate(formal_parameters_node.children):
                if child.type == "formal_parameter":
                    param_info = {"position": i}

                    # 提取参数类型
                    type_node = None
                    for param_child in child.children:
                        if param_child.type == "type_identifier" or param_child.type == "primitive_type" or param_child.type == "scoped_type_identifier":
                            type_node = param_child
                            break

                    if type_node:
                        param_info["type"] = self.get_node_text(type_node, code_bytes)

                    # 提取参数名
                    name_node = None
                    for param_child in child.children:
                        if param_child.type == "identifier":
                            name_node = param_child
                            break

                    if name_node:
                        param_info["name"] = self.get_node_text(name_node, code_bytes)

                    # 为参数添加full_name
                    if "name" in param_info and method_info.get("full_name"):
                        param_info["full_name"] = f"{method_info['full_name']}:param:{param_info['name']}"

                    parameters.append(param_info)

            method_info["parameters"] = json.dumps(parameters)

        # 构建方法签名
        param_types = []
        for param in json.loads(method_info.get("parameters", "[]")):
            if "type" in param:
                param_types.append(param["type"])

        method_info["signature"] = f"{method_info['name']}({', '.join(param_types)})"

        return method_info

    def _extract_field_info(self, node: Node, code_bytes: bytes, class_name: str = "", package_name: Optional[str] = None) -> Dict[str, Any]:
        """
        提取字段(变量)信息

        Args:
            node: 字段声明节点
            code_bytes: 源代码字节
            class_name: 字段所属类名
            package_name: 包名

        Returns:
            字段信息字典
        """
        field_info = {
            "node": node,
            "line_number": node.start_point[0] + 1,
            "is_static": False,
            "is_constant": False,
            "visibility": "default",
            "annotations": []  # 新增：存储注解列表
        }

        # 新增：提取字段注解
        self._extract_annotations(node, code_bytes, field_info)

        # 检查修饰符
        modifiers = self.find_all_nodes(node, "modifiers")
        if modifiers:
            for modifier in modifiers:
                modifier_text = self.get_node_text(modifier, code_bytes)
                if "public" in modifier_text:
                    field_info["visibility"] = "public"
                elif "private" in modifier_text:
                    field_info["visibility"] = "private"
                elif "protected" in modifier_text:
                    field_info["visibility"] = "protected"

                if "static" in modifier_text:
                    field_info["is_static"] = True

                if "final" in modifier_text:
                    field_info["is_constant"] = True

        # 提取字段类型
        type_node = None
        for child in node.children:
            if child.type == "type_identifier" or child.type == "primitive_type" or child.type == "scoped_type_identifier":
                type_node = child
                break

        if type_node:
            field_info["type"] = self.get_node_text(type_node, code_bytes)

        # 提取字段名和默认值
        variable_declarator_nodes = self.find_all_nodes(node, "variable_declarator")
        if variable_declarator_nodes:
            declarator_node = variable_declarator_nodes[0]

            # 提取变量名
            name_node = None
            for child in declarator_node.children:
                if child.type == "identifier":
                    name_node = child
                    break

            if name_node:
                field_info["name"] = self.get_node_text(name_node, code_bytes)

                # 设置class_name
                field_info["class_name"] = class_name

                # 添加full_name字段
                if class_name:
                    # 使用类的全限定名构建字段的全名
                    if package_name:
                        class_full_name = f"{package_name}.{class_name}"
                    else:
                        class_full_name = class_name

                    field_info["full_name"] = f"{class_full_name}.{field_info['name']}"
                else:
                    field_info["full_name"] = field_info["name"]

            # 提取默认值
            equals_node = None
            for i, child in enumerate(declarator_node.children):
                if child.type == "=" and i + 1 < len(declarator_node.children):
                    equals_node = declarator_node.children[i + 1]
                    break

            if equals_node:
                field_info["default_value"] = self.get_node_text(equals_node, code_bytes)

        return field_info

    def _extract_annotation_declaration_info(self, node: Node, code_bytes: bytes, package_name: Optional[str] = None) -> Dict[str, Any]:
        """
        提取注解声明信息

        Args:
            node: 注解声明节点
            code_bytes: 源代码字节
            package_name: 包名

        Returns:
            注解声明信息字典
        """
        annotation_info = {
            "node": node,
            "type": "annotation",
            "line_start": node.start_point[0] + 1,
            "line_end": node.end_point[0] + 1,
            "visibility": "default",
            "annotations": []  # 新增：存储注解上的注解
        }

        # 提取注解上的注解
        self._extract_annotations(node, code_bytes, annotation_info)

        # 获取注解名
        name_node = None
        for child in node.children:
            if child.type == "identifier":
                name_node = child
                break

        if name_node:
            annotation_info["name"] = self.get_node_text(name_node, code_bytes)
            if package_name:
                annotation_info["full_name"] = f"{package_name}.{annotation_info['name']}"
            else:
                annotation_info["full_name"] = annotation_info["name"]

        # 检查修饰符
        modifiers = self.find_all_nodes(node, "modifiers")
        if modifiers:
            for modifier in modifiers:
                modifier_text = self.get_node_text(modifier, code_bytes)
                if "public" in modifier_text:
                    annotation_info["visibility"] = "public"
                elif "private" in modifier_text:
                    annotation_info["visibility"] = "private"
                elif "protected" in modifier_text:
                    annotation_info["visibility"] = "protected"

        return annotation_info

    def extract_entities(self, tree: Tree, file_path: str, source_code: str = None) -> Dict[str, List[Dict[str, Any]]]:
        """
        从Java语法树中提取实体（文件、类、方法、变量、注释等）

        Args:
            tree: 语法树对象
            file_path: 文件路径
            source_code: 源代码字符串

        Returns:
            按实体类型分组的实体列表
        """
        # 如果未提供源代码，尝试从文件读取
        if source_code is None:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    source_code = f.read()
            except Exception as e:
                logger.error(f"无法读取文件内容: {str(e)}")
                return {"file": [], "class": [], "function": [], "variable": [], "comment": []}

        code_bytes = bytes(source_code, 'utf8')
        root_node = tree.root_node
        entities = {
            "file": [],
            "class": [],
            "function": [],
            "variable": [],
            "comment": [],
            "annotations": []  # 新增：注解实体
        }

        # 提取文件信息
        file_info = {
            "file_path": file_path,
            "name": os.path.basename(file_path),
            "extension": os.path.splitext(file_path)[1],
            "size": len(code_bytes),
            "last_modified": datetime.fromtimestamp(os.path.getmtime(file_path)).isoformat(),
            "language": "java"
        }
        entities["file"].append(file_info)

        # 提取包信息
        package_name = self._extract_package_info(root_node, code_bytes)

        # 提取导入信息
        imports = self._extract_imports(root_node, code_bytes)

        # 提取注释
        comment_nodes = self._get_comment_nodes(root_node)
        for comment in comment_nodes:
            comment_info = {
                "content": self.get_node_text(comment["node"], code_bytes),
                "type": comment["type"],
                "line_start": comment["line_start"],
                "line_end": comment["line_end"],
                "is_documentation": comment["type"] == "BLOCK" and self.get_node_text(comment["node"], code_bytes).startswith("/**")
            }
            entities["comment"].append(comment_info)

        # 提取类声明
        class_declarations = self.find_all_nodes(root_node, "class_declaration")
        for node in class_declarations:
            class_info = self._extract_class_info(node, code_bytes, package_name)
            entities["class"].append(class_info)

            # 提取方法
            method_declarations = self.find_all_nodes(node, "method_declaration")
            for method_node in method_declarations:
                method_info = self._extract_method_info(method_node, code_bytes, class_info.get("name", ""), package_name)
                entities["function"].append(method_info)

            # 提取字段
            field_declarations = self.find_all_nodes(node, "field_declaration")
            for field_node in field_declarations:
                field_info = self._extract_field_info(field_node, code_bytes, class_info.get("name", ""), package_name)
                entities["variable"].append(field_info)

        # 提取接口声明
        interface_declarations = self.find_all_nodes(root_node, "interface_declaration")
        for node in interface_declarations:
            interface_info = self._extract_interface_info(node, code_bytes, package_name)
            entities["class"].append(interface_info)

            # 提取接口方法
            method_declarations = self.find_all_nodes(node, "method_declaration")
            for method_node in method_declarations:
                method_info = self._extract_method_info(method_node, code_bytes, interface_info.get("name", ""), package_name)
                # 接口方法默认为抽象方法
                method_info["is_abstract"] = True
                entities["function"].append(method_info)

            # 提取接口常量
            field_declarations = self.find_all_nodes(node, "field_declaration")
            for field_node in field_declarations:
                field_info = self._extract_field_info(field_node, code_bytes, interface_info.get("name", ""), package_name)
                # 接口字段默认为常量
                field_info["is_constant"] = True
                entities["variable"].append(field_info)

        # 提取注解声明
        annotation_declarations = self.find_all_nodes(root_node, "annotation_type_declaration")
        for node in annotation_declarations:
            annotation_info = self._extract_annotation_declaration_info(node, code_bytes, package_name)
            entities["class"].append(annotation_info)  # 将注解类型添加到class集合中

            # 提取注解元素（类似于字段）
            annotation_element_declarations = self.find_all_nodes(node, "annotation_type_element_declaration")
            for element_node in annotation_element_declarations:
                element_info = {
                    "node": element_node,
                    "line_number": element_node.start_point[0] + 1,
                    "is_constant": True,
                    "visibility": "public",  # 注解元素默认是public的
                    "annotations": []
                }

                # 提取元素上的注解
                self._extract_annotations(element_node, code_bytes, element_info)

                # 提取元素名
                name_node = None
                for child in element_node.children:
                    if child.type == "identifier":
                        name_node = child
                        break

                if name_node:
                    element_info["name"] = self.get_node_text(name_node, code_bytes)
                    element_info["class_name"] = annotation_info.get("name", "")

                    # 添加full_name字段
                    if annotation_info.get("full_name"):
                        element_info["full_name"] = f"{annotation_info['full_name']}.{element_info['name']}"
                    else:
                        element_info["full_name"] = f"{element_info['class_name']}.{element_info['name']}"

                # 提取元素类型
                type_node = None
                for child in element_node.children:
                    if child.type == "type_identifier" or child.type == "primitive_type" or child.type == "scoped_type_identifier":
                        type_node = child
                        break

                if type_node:
                    element_info["type"] = self.get_node_text(type_node, code_bytes)

                # 提取默认值
                default_node = None
                for child in element_node.children:
                    if child.type == "default_value":
                        for default_child in child.children:
                            if default_child.type != "default":  # 跳过default关键字
                                default_node = default_child
                                break
                        break

                if default_node:
                    element_info["default_value"] = self.get_node_text(default_node, code_bytes)

                entities["variable"].append(element_info)

        # 创建注解实体
        self._create_annotation_entities(entities)

        return entities

    def extract_relationships(self, tree: Tree, file_path: str, entities: Dict[str, List[Dict[str, Any]]], source_code: str = None) -> List[Dict[str, Any]]:
        """
        从Java语法树中提取实体间的关系

        Args:
            tree: 语法树对象
            file_path: 文件路径
            entities: 已提取的实体
            source_code: 源代码字符串

        Returns:
            关系列表
        """
        # 如果未提供源代码，尝试从文件读取
        if source_code is None:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    source_code = f.read()
            except Exception as e:
                logger.error(f"无法读取文件内容: {str(e)}")
                return []

        code_bytes = bytes(source_code, 'utf8')
        root_node = tree.root_node
        relationships = []

        # 创建ID映射，用于后续建立关系
        entity_id_map = {
            "class": {},     # 类名 -> ID
            "function": {},  # 函数全名 -> ID
            "variable": {},  # 变量全名 -> ID
            "file": {},      # 文件路径 -> ID
            "comment": {}    # 注释ID -> 注释
        }

        # 记录所有已知的实体ID，用于后续一致性检查
        all_known_entities = set()

        # 文件ID
        file_id = os.path.abspath(file_path)
        entity_id_map["file"][file_path] = file_id
        all_known_entities.add(file_id)

        # 构建类ID映射
        for class_entity in entities.get("class", []):
            if "full_name" in class_entity:
                entity_id = class_entity["full_name"]
                entity_id_map["class"][class_entity["full_name"]] = entity_id
                all_known_entities.add(entity_id)

                # 1. 文件包含类的关系
                relationships.append({
                    "from_id": file_id,
                    "to_id": entity_id,
                    "type": "contains",
                    "properties": {
                        "visibility": class_entity.get("visibility", "default")
                    }
                })

                # 2. 类继承关系
                if "extends" in class_entity:
                    relationships.append({
                        "from_id": entity_id,
                        "to_id": class_entity["extends"],
                        "type": "extends",
                        "properties": {
                            "line_number": class_entity.get("line_start", 0)
                        }
                    })

                # 3. 类实现接口关系
                if "implements" in class_entity and isinstance(class_entity["implements"], list):
                    for interface in class_entity["implements"]:
                        relationships.append({
                            "from_id": entity_id,
                            "to_id": interface,
                            "type": "implements",
                            "properties": {
                                "line_number": class_entity.get("line_start", 0)
                            }
                        })

        # 构建函数ID映射并建立函数关系
        for function_entity in entities.get("function", []):
            if "full_name" in function_entity:
                entity_id = function_entity["full_name"]
                entity_id_map["function"][function_entity["full_name"]] = entity_id
                all_known_entities.add(entity_id)

                # 找到函数所属的类
                class_name = None
                if "full_name" in function_entity:
                    parts = function_entity["full_name"].split(".")
                    if len(parts) > 1:
                        class_name = ".".join(parts[:-1])

                if class_name and class_name in entity_id_map["class"]:
                    class_id = entity_id_map["class"][class_name]
                    # 4. 类包含方法的关系
                    relationships.append({
                        "from_id": class_id,
                        "to_id": entity_id,
                        "type": "contains",
                        "properties": {
                            "visibility": function_entity.get("visibility", "default")
                        }
                    })

                # 5. 方法参数关系 - 需要结合代码内部分析
                if "parameters" in function_entity and function_entity["parameters"]:
                    try:
                        params = json.loads(function_entity["parameters"])
                        for param in params:
                            if "name" in param and "type" in param:
                                # 使用参数的full_name作为ID（如果有）
                                if "full_name" in param:
                                    param_id = param["full_name"]
                                else:
                                    param_id = f"{function_entity['full_name']}:param:{param['name']}"

                                # 创建参数变量实体
                                param_entity = {
                                    "name": param["name"],
                                    "full_name": param.get("full_name", param_id),
                                    "type": param["type"],
                                    "line_number": function_entity.get("line_start", 0)
                                }

                                entities.setdefault("variable", []).append(param_entity)
                                entity_id_map["variable"][param_id] = param_id
                                all_known_entities.add(param_id)

                                # 建立方法与参数的关系 - 修改为contains关系
                                relationships.append({
                                    "from_id": entity_id,
                                    "to_id": param_id,
                                    "type": "contains",
                                    "properties": {
                                        "visibility": "default"
                                    }
                                })
                    except (json.JSONDecodeError, KeyError) as e:
                        logger.warning(f"解析方法参数失败: {str(e)}")

        # 构建变量ID映射并建立变量关系
        for variable_entity in entities.get("variable", []):
            if "name" in variable_entity:
                # 使用full_name作为变量ID（如果有）
                if "full_name" in variable_entity:
                    variable_id = variable_entity["full_name"]
                else:
                    # 兼容旧代码 - 生成变量ID
                    if "class_name" in variable_entity and variable_entity["class_name"]:
                        variable_id = f"{variable_entity['class_name']}.{variable_entity['name']}"
                    else:
                        variable_id = variable_entity["name"]

                entity_id_map["variable"][variable_id] = variable_id
                all_known_entities.add(variable_id)

                # 找到变量所属的类
                class_name = variable_entity.get("class_name")
                if class_name:
                    # 获取包名，构建类的全限定名
                    package_name = self._extract_package_info(root_node, code_bytes) or ""
                    if package_name:
                        full_class_name = f"{package_name}.{class_name}"
                    else:
                        full_class_name = class_name

                    # 查找类ID
                    if full_class_name in entity_id_map["class"]:
                        class_id = entity_id_map["class"][full_class_name]

                        # 6. 类包含变量的关系
                        relationships.append({
                            "from_id": class_id,
                            "to_id": variable_id,
                            "type": "contains",
                            "properties": {
                                "visibility": variable_entity.get("visibility", "default")
                            }
                        })

        # 构建注释ID映射并添加documented_by关系
        comment_entities = entities.get("comment", [])
        for comment_entity in comment_entities:
            line_start = comment_entity.get("line_start", 0)
            line_end = comment_entity.get("line_end", 0)
            # 为注释生成唯一ID
            file_path_for_id = entities.get("file", [{}])[0].get("file_path", "unknown")
            comment_id = f"comment:{file_path_for_id}:{line_start}"

            entity_id_map["comment"][comment_id] = comment_id
            all_known_entities.add(comment_id)

            # 判断是否为文档注释 (JavaDoc)
            is_javadoc = comment_entity.get("is_documentation", False)

            # 找到紧随注释之后的代码实体
            if is_javadoc:
                # 为各类代码实体创建documented_by关系
                for entity_type in ["class", "function", "variable"]:
                    for entity in entities.get(entity_type, []):
                        entity_line_start = entity.get("line_start") or entity.get("line_number", 0)

                        # 判断注释是否紧邻代码实体 (通常JavaDoc注释紧接在代码实体之前)
                        if line_end + 1 == entity_line_start:
                            entity_id = None
                            if "full_name" in entity:
                                entity_id = entity["full_name"]
                            elif entity_type == "variable" and "name" in entity:
                                if "class_name" in entity and entity["class_name"]:
                                    entity_id = f"{entity['class_name']}.{entity['name']}"
                                else:
                                    entity_id = entity["name"]

                            if entity_id and entity_id in all_known_entities:
                                # 创建 documented_by 关系
                                relationships.append({
                                    "from_id": entity_id,
                                    "to_id": comment_id,
                                    "type": "documented_by",
                                    "properties": {

                                    }
                                })
                                # 一个文档注释通常只对应一个实体，找到后就跳出内层循环
                                break
            else:
                # 处理普通注释的关系 - 可能是行内注释或相关说明注释
                # 查找注释所在行附近的代码实体
                for entity_type in ["function"]:  # 暂时只处理函数内的注释
                    for entity in entities.get(entity_type, []):
                        entity_line_start = entity.get("line_start", 0)
                        entity_line_end = entity.get("line_end", 0)

                        # 判断注释是否在代码实体内部
                        if entity_line_start <= line_start <= entity_line_end:
                            if "full_name" in entity:
                                # 创建 documented_by 关系
                                relationships.append({
                                    "from_id": entity["full_name"],
                                    "to_id": comment_id,
                                    "type": "documented_by",
                                    "properties": {

                                    }
                                })

        # 提取变量声明和类型关系
        variable_declarations = self.find_all_nodes(root_node, "local_variable_declaration")
        for node in variable_declarations:
            # 获取变量类型
            var_type = None
            for child in node.children:
                if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                    var_type = self.get_node_text(child, code_bytes)
                    break

            # 获取变量名
            var_name = None
            for child in node.children:
                if child.type == "variable_declarator":
                    for sub_child in child.children:
                        if sub_child.type == "identifier":
                            var_name = self.get_node_text(sub_child, code_bytes)
                            break
                    if var_name:
                        break

            # 找到包含该变量声明的方法
            container_method = None
            container_class = None
            parent = node.parent
            while parent:
                if parent.type == "method_declaration":
                    # 获取方法名
                    for child in parent.children:
                        if child.type == "identifier":
                            container_method = self.get_node_text(child, code_bytes)
                            break
                elif parent.type == "class_declaration":
                    # 获取类名
                    for child in parent.children:
                        if child.type == "identifier":
                            container_class = self.get_node_text(child, code_bytes)
                            break
                    break
                parent = parent.parent

            # 找到方法ID
            method_id = None
            if container_method and container_class:
                # 提取包名
                package_name = self._extract_package_info(root_node, code_bytes) or ""
                if package_name:
                    full_method_name = f"{package_name}.{container_class}.{container_method}"
                else:
                    full_method_name = f"{container_class}.{container_method}"

                for method_full_name in entity_id_map["function"]:
                    if method_full_name == full_method_name:
                        method_id = method_full_name
                        break

            # 如果找到变量类型、变量名和方法ID，建立"uses"关系
            if var_type and var_name and method_id:
                # 检查变量类型是否为自定义类型（非Java基本类型）
                basic_types = ["int", "long", "double", "float", "boolean", "char", "byte", "short", "String", "Object"]
                if var_type not in basic_types and not var_type.startswith("java."):
                    # 11. 方法使用类型关系
                    relationships.append({
                        "from_id": method_id,
                        "to_id": var_type,
                        "type": "depends_on",
                        "properties": {
                            "dependency_type": "VARIABLE_DECLARATION",
                            "line_number": node.start_point[0] + 1
                        }
                    })

                    # 12. 文件依赖关系
                    relationships.append({
                        "from_id": file_id,
                        "to_id": var_type,
                        "type": "depends_on",
                        "properties": {
                            "dependency_type": "CLASS_USAGE",
                            "line_number": node.start_point[0] + 1
                        }
                    })

        # 提取对象创建表达式（new操作符）来确定类依赖关系
        object_creation_nodes = self.find_all_nodes(root_node, "object_creation_expression")
        for node in object_creation_nodes:
            # 获取创建的类型
            created_type = None
            for child in node.children:
                if child.type == "type_identifier" or child.type == "scoped_type_identifier":
                    created_type = self.get_node_text(child, code_bytes)
                    break

            # 找到包含该对象创建的方法
            container_method = None
            container_class = None
            parent = node.parent
            while parent:
                if parent.type == "method_declaration":
                    # 获取方法名
                    for child in parent.children:
                        if child.type == "identifier":
                            container_method = self.get_node_text(child, code_bytes)
                            break
                elif parent.type == "class_declaration":
                    # 获取类名
                    for child in parent.children:
                        if child.type == "identifier":
                            container_class = self.get_node_text(child, code_bytes)
                            break
                    break
                parent = parent.parent

            # 找到方法ID
            method_id = None
            class_id = None
            if container_method and container_class:
                # 提取包名
                package_name = self._extract_package_info(root_node, code_bytes) or ""
                if package_name:
                    full_method_name = f"{package_name}.{container_class}.{container_method}"
                    full_class_name = f"{package_name}.{container_class}"
                else:
                    full_method_name = f"{container_class}.{container_method}"
                    full_class_name = container_class

                # 查找方法ID
                for method_full_name in entity_id_map["function"]:
                    if method_full_name == full_method_name:
                        method_id = method_full_name
                        break

                # 查找类ID
                class_id = entity_id_map["class"].get(full_class_name, full_class_name)

            # 如果找到创建的类型和方法ID，建立"depends_on"关系
            if created_type and method_id:
                # 13. 方法创建类型关系
                relationships.append({
                    "from_id": method_id,
                    "to_id": created_type,
                    "type": "depends_on",
                    "properties": {
                        "dependency_type": "CREATES",
                        "line_number": node.start_point[0] + 1
                    }
                })

                # 14. 类依赖关系
                if class_id:
                    # 15. 类依赖关系
                    relationships.append({
                        "from_id": class_id,
                        "to_id": created_type,
                        "type": "depends_on",
                        "properties": {
                            "dependency_type": "INSTANTIATION",
                            "line_number": node.start_point[0] + 1
                        }
                    })

                # 16. 文件依赖关系
                relationships.append({
                    "from_id": file_id,
                    "to_id": created_type,
                    "type": "depends_on",
                    "properties": {
                        "dependency_type": "CLASS_INSTANTIATION",
                        "line_number": node.start_point[0] + 1
                    }
                })

                # 添加到已知实体
                all_known_entities.add(created_type)

        # 提取类的关联关系（一个类使用另一个类作为成员变量）
        for variable_entity in entities.get("variable", []):
            if "name" in variable_entity and "type" in variable_entity and "class_name" in variable_entity:
                var_type = variable_entity["type"]
                container_class = variable_entity["class_name"]

                # 检查变量类型是否为自定义类型（非Java基本类型）
                basic_types = ["int", "long", "double", "float", "boolean", "char", "byte", "short", "String", "Object"]
                primitive_arrays = ["int[]", "long[]", "double[]", "float[]", "boolean[]", "char[]", "byte[]", "short[]"]
                collection_types = ["List", "ArrayList", "Set", "HashSet", "Map", "HashMap", "Collection"]

                # 排除基本类型、原始数组、Java集合类型和以java.开头的标准库类型
                if (var_type not in basic_types and
                    var_type not in primitive_arrays and
                    var_type not in collection_types and
                    not var_type.startswith("java.")):

                    # 获取包名
                    package_name = self._extract_package_info(root_node, code_bytes) or ""

                    # 构建完整类名
                    if package_name:
                        container_full_name = f"{package_name}.{container_class}"
                    else:
                        container_full_name = container_class

                    # 检查容器类是否在已知实体中
                    if container_full_name in entity_id_map["class"]:
                        container_id = entity_id_map["class"][container_full_name]

                        # 创建关联关系（容器类与成员变量类型之间的关系）转为depends_on
                        relationships.append({
                            "from_id": container_id,
                            "to_id": var_type,
                            "type": "depends_on",
                            "properties": {
                                "dependency_type": "ASSOCIATION",
                                "line_number": variable_entity.get("line_number", 0),
                            }
                        })

                        # 如果成员变量是集合类型且包含泛型类型信息，提取泛型类型并创建关系
                        if "<" in var_type and ">" in var_type:
                            generic_type = var_type[var_type.find("<")+1:var_type.rfind(">")]

                            # 处理多个泛型参数 (如 Map<String, User>)
                            generic_types = [t.strip() for t in generic_type.split(",")]

                            for gen_type in generic_types:
                                # 排除基本类型和Java标准库类型
                                if (gen_type not in basic_types and
                                    not gen_type.startswith("java.") and
                                    gen_type != "String" and
                                    gen_type != "Object"):

                                    relationships.append({
                                        "from_id": container_id,
                                        "to_id": gen_type,
                                        "type": "depends_on",
                                        "properties": {
                                            "dependency_type": "ASSOCIATION",
                                            "line_number": variable_entity.get("line_number", 0)
                                        }
                                    })

        # 处理类、方法和变量与注解之间的依赖关系
        for entity_type in ["class", "function", "variable"]:
            for entity in entities.get(entity_type, []):
                if "annotations" in entity and entity["annotations"]:
                    entity_id = None

                    # 获取实体ID
                    if "full_name" in entity:
                        entity_id = entity["full_name"]
                    elif entity_type == "variable" and "name" in entity:
                        if "class_name" in entity and entity["class_name"]:
                            entity_id = f"{entity['class_name']}.{entity['name']}"
                        else:
                            entity_id = entity["name"]

                    if entity_id and entity_id in all_known_entities:
                        # 为每个注解创建depends_on关系
                        for annotation in entity["annotations"]:
                            if "full_name" in annotation:
                                annotation_id = annotation["full_name"]

                                # 注解关系已经在convert_to_graph中处理
                                # 这里不再创建注解关系
                                # 使用annotation_id变量避免IDE警告
                                _ = annotation_id

                                # 添加可能的注解参数
                                if "parameters" in annotation:
                                    for _, param_value in annotation["parameters"].items():
                                        # 如果参数值看起来像类引用，添加额外的depends_on关系
                                        if (isinstance(param_value, str) and
                                            param_value.strip('"\'').startswith(tuple('ABCDEFGHIJKLMNOPQRSTUVWXYZ')) and
                                            not param_value.startswith(("\"", "'"))):

                                            param_class_id = param_value.strip('"\'')
                                            relationships.append({
                                                "from_id": entity_id,
                                                "to_id": param_class_id,
                                                "type": "depends_on",
                                                "properties": {
                                                    "dependency_type": "ANNOTATION_PARAMETER",
                                                    "line_number": entity.get("line_start") or entity.get("line_number", 0)
                                                }
                                            })

        # 完成后，对所有关系进行一致性检查
        consistent_relationships = []
        for rel in relationships:
            # 检查关系的两端ID是否已经在已知实体中或者已处理过的关系中
            from_id = rel["from_id"]
            to_id = rel["to_id"]

            # 特殊处理import关系，允许引用外部库
            if rel["type"] == "imports":
                consistent_relationships.append(rel)
                continue

            # 只保留至少一端是已知实体的关系
            if from_id in all_known_entities or to_id in all_known_entities:
                consistent_relationships.append(rel)

                # 如果有一端不是已知实体，记录一个警告
                if from_id not in all_known_entities:
                    logger.debug(f"关系中的源ID不是已知实体: {from_id}")
                if to_id not in all_known_entities:
                    logger.debug(f"关系中的目标ID不是已知实体: {to_id}")
            else:
                logger.warning(f"跳过关系，两端均不是已知实体: {from_id} -> {to_id}")

        return consistent_relationships

    def convert_to_graph(self, graph_connection, entities: Dict[str, List[Dict[str, Any]]], relationships: List[Dict[str, Any]]) -> bool:
        """
        将提取的实体和关系转换为NebulaGraph中的顶点和边

        Args:
            graph_connection: NebulaGraph连接对象
            entities: 按类型分组的实体列表
            relationships: 关系列表

        Returns:
            转换是否成功
        """
        try:
            success = True

            # 获取当前时间戳
            current_timestamp = int(time.time())

            # 1. 创建文件顶点
            for file_entity in entities.get("file", []):
                vertex_id = os.path.abspath(file_entity["file_path"])
                self.id_mappings[file_entity["file_path"]] = vertex_id
                if vertex_id not in self.created_vertices:
                    properties = {
                        "file_path": file_entity["file_path"],
                        "name": file_entity["name"],
                        "extension": file_entity.get("extension", ""),
                        "last_modified": file_entity.get("last_modified", ""),
                        "language": file_entity.get("language", "java"),
                        "last_updated": current_timestamp
                    }

                    if not graph_connection.create_vertex("file", vertex_id, properties):
                        logger.warning(f"创建文件顶点失败: {vertex_id}")
                        success = False
                    else:
                        self.created_vertices.add(vertex_id)

            # 2. 创建类顶点
            for class_entity in entities.get("class", []):
                if "full_name" in class_entity:
                    vertex_id = class_entity["full_name"]
                    self.id_mappings[vertex_id] = vertex_id

                    # 主要变更：检查是否是占位符或新节点
                    is_new_node = vertex_id not in self.created_vertices
                    is_placeholder = vertex_id in self.placeholder_vertices

                    # 如果是新节点或者是占位符，则创建/更新节点
                    if is_new_node or is_placeholder:
                        # 获取类的文本内容并压缩
                        class_content = ""
                        if "node" in class_entity:
                            try:
                                class_content = class_entity["node"].text.decode("utf-8")
                                class_content = ContentCompressor.compress(class_content)
                            except Exception as e:
                                logger.warning(f"获取类内容失败: {str(e)}")

                        properties = {
                            "name": class_entity.get("name", ""),
                            "full_name": class_entity["full_name"],
                            "visibility": class_entity.get("visibility", "default"),
                            "line_start": class_entity.get("line_start", 0),
                            "line_end": class_entity.get("line_end", 0),
                            "last_updated": current_timestamp,
                            "type": class_entity.get("type", ""),
                            "content": class_content  # 添加压缩后的内容
                        }

                        if not graph_connection.create_vertex("class", vertex_id, properties):
                            logger.warning(f"创建类顶点失败: {vertex_id}")
                            success = False
                        else:
                            self.created_vertices.add(vertex_id)

            # 3. 创建函数顶点
            for function_entity in entities.get("function", []):
                if "full_name" in function_entity:
                    vertex_id = function_entity["full_name"]
                    self.id_mappings[vertex_id] = vertex_id
                    if vertex_id not in self.created_vertices:
                        # 获取函数的文本内容并压缩
                        function_content = ""
                        if "node" in function_entity:
                            try:
                                function_content = function_entity["node"].text.decode("utf-8")
                                function_content = ContentCompressor.compress(function_content)
                            except Exception as e:
                                logger.warning(f"获取函数内容失败: {str(e)}")

                        properties = {
                            "name": function_entity.get("name", ""),
                            "full_name": function_entity["full_name"],
                            "visibility": function_entity.get("visibility", "default"),
                            "is_static": function_entity.get("is_static", False),
                            "is_constructor": function_entity.get("is_constructor", False),
                            "line_start": function_entity.get("line_start", 0),
                            "line_end": function_entity.get("line_end", 0),
                            "last_updated": current_timestamp,
                            "content": function_content  # 添加压缩后的内容
                        }

                        if not graph_connection.create_vertex("function", vertex_id, properties):
                            logger.warning(f"创建函数顶点失败: {vertex_id}")
                            success = False
                        else:
                            self.created_vertices.add(vertex_id)

            # 4. 创建变量顶点
            for variable_entity in entities.get("variable", []):
                if "name" in variable_entity:
                    # 使用full_name作为变量ID（如果有）
                    if "full_name" in variable_entity:
                        variable_id = variable_entity["full_name"]
                    else:
                        # 兼容旧代码 - 生成变量ID
                        if "class_name" in variable_entity and variable_entity["class_name"]:
                            variable_id = f"{variable_entity['class_name']}.{variable_entity['name']}"
                        else:
                            variable_id = variable_entity["name"]

                    self.id_mappings[variable_id] = variable_id
                    if variable_id not in self.created_vertices:
                        # 获取变量的文本内容并压缩
                        variable_content = ""
                        if "node" in variable_entity:
                            try:
                                variable_content = variable_entity["node"].text.decode("utf-8")
                                variable_content = ContentCompressor.compress(variable_content)
                            except Exception as e:
                                logger.warning(f"获取变量内容失败: {str(e)}")

                        properties = {
                            "name": variable_entity["name"],
                            "full_name": variable_entity.get("full_name", variable_id),
                            "type": variable_entity.get("type", ""),
                            "visibility": variable_entity.get("visibility", "default"),
                            "is_static": variable_entity.get("is_static", False),
                            "is_constant": variable_entity.get("is_constant", False),
                            "line_number": variable_entity.get("line_number", 0),
                            "last_updated": current_timestamp,
                            "content": variable_content  # 添加压缩后的内容
                        }

                        if not graph_connection.create_vertex("variable", variable_id, properties):
                            logger.warning(f"创建变量顶点失败: {variable_id}")
                            success = False
                        else:
                            self.created_vertices.add(variable_id)

            # 5. 创建注释顶点
            for comment_entity in entities.get("comment", []):
                if "content" in comment_entity:
                    # 为注释生成唯一ID
                    line_start = comment_entity.get("line_start", 0)
                    file_path = entities.get("file", [{}])[0].get("file_path", "unknown")
                    comment_id = f"comment:{file_path}:{line_start}"

                    self.id_mappings[comment_id] = comment_id
                    if comment_id not in self.created_vertices:
                        # 压缩注释内容
                        comment_content = comment_entity["content"]
                        compressed_content = ContentCompressor.compress(comment_content)

                        properties = {
                            "content": comment_entity["content"],  # 保留原始内容用于显示
                            "type": comment_entity.get("type", "LINE"),
                            "line_start": line_start,
                            "line_end": comment_entity.get("line_end", line_start),
                            "last_updated": current_timestamp,
                            "content": compressed_content  # 添加压缩后的内容
                        }

                        if not graph_connection.create_vertex("comment", comment_id, properties):
                            logger.warning(f"创建注释顶点失败: {comment_id}")
                            success = False
                        else:
                            self.created_vertices.add(comment_id)

            # 5.1 创建注解顶点
            for annotation_entity in entities.get("annotations", []):
                if "full_name" in annotation_entity:
                    vertex_id = annotation_entity["full_name"]
                    self.id_mappings[vertex_id] = vertex_id
                    if vertex_id not in self.created_vertices:
                        properties = {
                            "name": annotation_entity.get("name", ""),
                            "full_name": annotation_entity["full_name"],
                            "type": annotation_entity.get("type", "ANNOTATION"),
                            "line_start": annotation_entity.get("line_start", 0),
                            "line_end": annotation_entity.get("line_end", 0),
                            "last_updated": current_timestamp
                        }

                        # 添加注解参数（如果有）
                        if "parameters" in annotation_entity:
                            # 将参数存储在content字段中，并进行压缩
                            params_json = json.dumps(annotation_entity["parameters"])
                            properties["content"] = ContentCompressor.compress(params_json)

                        if not graph_connection.create_vertex("annotations", vertex_id, properties):
                            logger.warning(f"创建注解顶点失败: {vertex_id}")
                            success = False
                        else:
                            self.created_vertices.add(vertex_id)

                            # 创建注解实体与注解类之间的关系
                            if "annotation_class" in annotation_entity:
                                annotation_class_id = annotation_entity["annotation_class"]
                                if annotation_class_id in self.created_vertices:
                                    # 创建注解实体到注解类的depends_on关系
                                    if not graph_connection.create_edge("depends_on", vertex_id, annotation_class_id, {
                                        "dependency_type": "IMPLEMENTS",
                                        "line_number": annotation_entity.get("line_start", 0)
                                    }):
                                        logger.warning(f"创建注解实体到注解类的关系失败: {vertex_id} -> {annotation_class_id}")

                            # 创建注解实体与被注解实体之间的关系
                            if "entity_id" in annotation_entity:
                                entity_id = annotation_entity["entity_id"]
                                if entity_id in self.created_vertices:
                                    # 创建注解实体到被注解实体的depends_on关系
                                    if not graph_connection.create_edge("depends_on", vertex_id, entity_id, {
                                        "dependency_type": "ANNOTATES",
                                        "line_number": annotation_entity.get("line_start", 0)
                                    }):
                                        logger.warning(f"创建注解实体到被注解实体的关系失败: {vertex_id} -> {entity_id}")

                                    # 创建被注解实体到注解实体的depends_on关系
                                    if not graph_connection.create_edge("depends_on", entity_id, vertex_id, {
                                        "dependency_type": "ANNOTATION_USAGE",
                                        "line_number": annotation_entity.get("line_start", 0)
                                    }):
                                        logger.warning(f"创建被注解实体到注解实体的关系失败: {entity_id} -> {vertex_id}")

            # 6. 处理关系中可能需要的额外顶点
            # 收集未创建的实体ID
            missing_entities = set()
            for relationship in relationships:
                from_id = relationship.get("from_id")
                to_id = relationship.get("to_id")

                # 检查源ID
                if from_id and from_id not in self.created_vertices and from_id not in self.id_mappings:
                    missing_entities.add(from_id)

                # 检查目标ID
                if to_id and to_id not in self.created_vertices and to_id not in self.id_mappings:
                    missing_entities.add(to_id)

            # 处理缺失的实体ID
            for entity_id in missing_entities:
                # 跳过注释ID
                if entity_id.startswith("comment:"):
                    continue

                # 处理类(包括外部类和接口)
                if "." in entity_id and not entity_id.endswith(")") and not ":" in entity_id:
                    # 看起来像一个类名 (包含点但不是方法签名也不是参数)
                    class_name = entity_id.split(".")[-1]  # 获取类的简单名称

                    logger.info(f"为缺失的引用创建占位符类顶点: {entity_id}")
                    properties = {
                        "name": class_name,
                        "full_name": entity_id,
                        "is_external": True,  # 标记为外部类
                        "last_updated": current_timestamp
                    }

                    if not graph_connection.create_vertex("class", entity_id, properties):
                        logger.warning(f"创建占位符类顶点失败: {entity_id}")
                        success = False
                    else:
                        self.created_vertices.add(entity_id)
                        self.id_mappings[entity_id] = entity_id
                        # 标记为占位符节点
                        self.placeholder_vertices.add(entity_id)

                # 处理没有包名的类（如UserService）
                elif not "." in entity_id and not ":" in entity_id and not entity_id.startswith("/"):
                    # 看起来像一个没有包名的类名
                    logger.info(f"为缺失的引用创建占位符简单类顶点: {entity_id}")
                    properties = {
                        "name": entity_id,
                        "full_name": entity_id,
                        "last_updated": current_timestamp
                    }

                    if not graph_connection.create_vertex("class", entity_id, properties):
                        logger.warning(f"创建占位符简单类顶点失败: {entity_id}")
                        success = False
                    else:
                        self.created_vertices.add(entity_id)
                        self.id_mappings[entity_id] = entity_id
                        # 标记为占位符节点
                        self.placeholder_vertices.add(entity_id)

            # 7. 创建关系边，确保使用映射后的ID和转换后的关系类型
            for relationship in relationships:
                from_id_original = relationship.get("from_id")
                to_id_original = relationship.get("to_id")
                rel_type = relationship.get("type")
                properties = relationship.get("properties", {})

                # 使用ID映射获取最终ID
                from_id = self.id_mappings.get(from_id_original, from_id_original)
                to_id = self.id_mappings.get(to_id_original, to_id_original)

                # 记录ID映射情况
                if from_id != from_id_original:
                    logger.debug(f"已映射关系源ID: {from_id_original} -> {from_id}")
                if to_id != to_id_original:
                    logger.debug(f"已映射关系目标ID: {to_id_original} -> {to_id}")

                # 确保关系类型为五种核心关系之一
                valid_rel_types = ["contains", "extends", "implements", "depends_on", "documented_by"]
                if rel_type not in valid_rel_types:
                    # 映射其他关系类型到depends_on，并添加原始类型信息
                    if "dependency_type" not in properties:
                        properties["dependency_type"] = rel_type.upper()
                    original_type = rel_type
                    rel_type = "depends_on"
                    logger.debug(f"映射关系类型: {original_type} -> {rel_type}")

                if from_id and to_id and rel_type:
                    # 确保顶点已创建
                    if from_id in self.created_vertices and to_id in self.created_vertices:
                        if not graph_connection.create_edge(rel_type, from_id, to_id, properties):
                            logger.warning(f"创建关系边失败: {from_id} -> {to_id} ({rel_type})")
                            success = False
                    else:
                        # 记录详细的缺失顶点信息
                        missing_vertices = []
                        if from_id not in self.created_vertices:
                            missing_vertices.append(f"起始顶点: {from_id}")
                        if to_id not in self.created_vertices:
                            missing_vertices.append(f"目标顶点: {to_id}")

                        logger.warning(f"关系 {from_id} -> {to_id} ({rel_type}) 的顶点不存在: {', '.join(missing_vertices)}")

            # 8. 处理向量存储 - 如果启用了向量存储功能
            if self.enable_vector_storage and self.vector_processor:
                # 处理实体向量化
                vector_stats = self.vector_processor.process_entities(entities)
                logger.info(f"向量存储处理统计: {json.dumps(vector_stats)}")

            return success
        except Exception as e:
            logger.error(f"转换到图数据库失败: {str(e)}")
            return False

    def __del__(self):
        """析构函数，确保在对象被销毁时关闭资源"""
        if hasattr(self, 'vector_processor') and self.vector_processor:
            try:
                self.vector_processor.close()
            except Exception as e:
                logger.error(f"关闭向量处理器失败: {str(e)}")

    def _extract_annotations(self, node: Node, code_bytes: bytes, entity_info: Dict[str, Any]) -> None:
        """
        提取节点上的注解信息

        Args:
            node: AST节点
            code_bytes: 源代码字节
            entity_info: 实体信息字典，将在此添加注解
        """
        # 获取树的根节点
        root_node = node
        while root_node.parent is not None:
            root_node = root_node.parent

        # 首先在节点下直接查找注解
        self._process_annotation_nodes(node.children, code_bytes, entity_info, root_node)

        # 然后查找modifiers子节点，并在其下查找注解
        for child in node.children:
            if child.type == "modifiers":
                self._process_annotation_nodes(child.children, code_bytes, entity_info, root_node)

    def _process_annotation_nodes(self, nodes: List[Node], code_bytes: bytes, entity_info: Dict[str, Any], root_node: Node) -> None:
        """
        处理注解节点列表

        Args:
            nodes: 节点列表
            code_bytes: 源代码字节
            entity_info: 实体信息字典，将在此添加注解
            root_node: AST的根节点
        """
        for child in nodes:
            if child.type == "annotation" or child.type == "marker_annotation":
                annotation_info = {}

                # 默认设置为标记注解
                annotation_info["type"] = "MARKER_ANNOTATION"

                # 获取注解名称
                for annotation_child in child.children:
                    if annotation_child.type == "identifier" or annotation_child.type == "scoped_identifier":
                        annotation_name = self.get_node_text(annotation_child, code_bytes)
                        annotation_info["name"] = annotation_name

                        # 尝试获取包名组成全名
                        if "." not in annotation_name:
                            # 通过import推断完整包名
                            package_name = self._find_annotation_package(root_node, annotation_name, code_bytes)
                            if package_name:
                                annotation_info["full_name"] = f"{package_name}.{annotation_name}"
                            else:
                                annotation_info["full_name"] = annotation_name
                        else:
                            annotation_info["full_name"] = annotation_name

                        break

                # 获取注解参数（如果有）
                annotation_params = {}
                annotation_argument_list = None

                for annotation_child in child.children:
                    if annotation_child.type == "annotation_argument_list":
                        annotation_argument_list = annotation_child
                        break

                if annotation_argument_list:
                    for arg_child in annotation_argument_list.children:
                        if arg_child.type == "annotation_element":
                            key = None
                            value = None

                            for elem_child in arg_child.children:
                                if elem_child.type == "identifier":
                                    key = self.get_node_text(elem_child, code_bytes)
                                elif elem_child.type in ["string_literal", "integer_literal", "decimal_literal", "true", "false"]:
                                    value = self.get_node_text(elem_child, code_bytes)

                            if key and value:
                                annotation_params[key] = value
                        elif arg_child.type in ["string_literal", "integer_literal", "decimal_literal", "true", "false"]:
                            # 处理无键的值（例如 @SuppressWarnings("unchecked")）
                            annotation_params["value"] = self.get_node_text(arg_child, code_bytes)

                if annotation_params:
                    annotation_info["parameters"] = annotation_params
                    # 如果有参数，则是带信息的注解
                    annotation_info["type"] = "ANNOTATION"

                # 保存原始AST节点
                annotation_info["node"] = child

                # 将注解添加到实体中
                if annotation_info:
                    entity_info["annotations"].append(annotation_info)

    def _create_annotation_entities(self, entities: Dict[str, List[Dict[str, Any]]]) -> None:
        """
        从已提取的实体中创建注解实体

        Args:
            entities: 已提取的实体字典
        """
        # 遍历所有实体类型
        for entity_type in ["class", "function", "variable"]:
            for entity in entities.get(entity_type, []):
                if "annotations" in entity and entity["annotations"]:
                    # 获取实体ID
                    entity_id = None
                    if "full_name" in entity:
                        entity_id = entity["full_name"]
                    elif entity_type == "variable" and "name" in entity:
                        if "class_name" in entity and entity["class_name"]:
                            entity_id = f"{entity['class_name']}.{entity['name']}"
                        else:
                            entity_id = entity["name"]

                    if not entity_id:
                        continue

                    # 处理实体上的每个注解
                    for annotation in entity["annotations"]:
                        if "full_name" in annotation:
                            annotation_class_id = annotation["full_name"]

                            # 创建注解实例实体，vid是使用实体的full_name+注解的full_name
                            annotation_instance_id = f"{entity_id}@{annotation_class_id}"

                            # 创建注解实体
                            annotation_entity = {
                                "name": annotation.get("name", ""),
                                "full_name": annotation_instance_id,
                                "annotation_class": annotation_class_id,  # 添加对应的注解类引用
                                "entity_id": entity_id,  # 添加被注解实体的引用
                                "type": annotation.get("type", "ANNOTATION"),  # 使用原始注解的类型，默认为标准注解
                                "line_start": entity.get("line_start") or entity.get("line_number", 0),
                                "line_end": entity.get("line_end") or entity.get("line_number", 0)
                            }

                            # 如果原始注解有node属性，将其保存到注解实体中
                            if "node" in annotation:
                                annotation_entity["node"] = annotation["node"]

                            # 如果有参数，添加到注解实体中
                            if "parameters" in annotation:
                                annotation_entity["parameters"] = annotation["parameters"]

                            # 添加到注解实体列表
                            entities["annotations"].append(annotation_entity)

    def _find_annotation_package(self, root_node: Node, annotation_name: str, code_bytes: bytes) -> Optional[str]:
        """
        尝试从导入语句中找到注解的包名

        Args:
            root_node: 语法树根节点
            annotation_name: 注解名称
            code_bytes: 源代码字节

        Returns:
            注解的包名或None
        """
        import_nodes = self.find_all_nodes(root_node, "import_declaration")

        # 尝试直接匹配导入语句
        for node in import_nodes:
            import_text = self.get_node_text(node, code_bytes)

            # 检查是否直接导入了这个注解
            if import_text.endswith("." + annotation_name + ";"):
                # 提取包名
                package_part = import_text.replace("import ", "").replace(";", "")
                package_part = package_part.strip()
                if package_part.endswith("." + annotation_name):
                    return package_part[:-len("." + annotation_name)]

            # 检查是否使用星号导入了包含该注解的包
            if import_text.endswith(".*"):
                package_part = import_text.replace("import ", "").replace(".*;", "").strip()
                # 这里我们只能返回可能的包，因为我们不能确定星号导入中是否包含该注解
                # 在实际情况中可能需要通过类路径检查
                return package_part

        # 如果找不到匹配的导入，返回None
        return None